package com.sdksoft.readcard

import android.content.Intent
import android.net.Uri
import android.nfc.NdefMessage
import android.nfc.NdefRecord
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.Ndef
import android.nfc.tech.NdefFormatable
import android.text.TextUtils
import android.util.Log
import android.view.View
import com.csht.enums.ReadCardType
import com.sdksoft.readcard.databinding.LayoutNfcTagBinding
import com.sdksoft.readcard.utils.UriPrefixMap
import com.csht.utils.HHTipUtils
import com.csht.utils.LogUtils
import com.csht.utils.NfcUtils
import java.util.Arrays


/**
 * NFC标签
 */
class NFCTAGActivity : BaseInitActivity() {
    //1.声明一个nfc的Adapter
    private lateinit var nfcUtils: NfcUtils

    private val TAG = "NFCTAG"

    private lateinit var layoutNfcTagBinding: LayoutNfcTagBinding

    private var isReadTAG = true

    override fun initView() {
        super.initView()
        setTitleText("NFC标签")
        layoutNfcTagBinding = LayoutNfcTagBinding.inflate(layoutInflater)
        baseActivityBinding.llContent.apply{
            addView(layoutNfcTagBinding.root, 0)
        }
        nfcUtils = NfcUtils(this, this.javaClass)
        readSettingBuilder.buildReadCardType(ReadCardType.NFC)
        layoutNfcTagBinding.apply {
            tvLog.text = "---------开始读取标签------>"
            tvLog.setOnLongClickListener {
                tvLog.text = ""
                HHTipUtils.getInstance().showToast(this@NFCTAGActivity, "已清空日志")
                return@setOnLongClickListener true
            }
            btnReadTAG.setOnClickListener {
                isReadTAG = true
                HHTipUtils.getInstance().showToast(this@NFCTAGActivity, "开始读取标签")
                appendLog("\n---------开始读取标签------>")
            }
            btnWrTAG.setOnClickListener {
                if (TextUtils.isEmpty(etContent.text.toString().trim())) {
                    HHTipUtils.getInstance().showToast(this@NFCTAGActivity, "请输入内容")
                    return@setOnClickListener
                }
                appendLog("\n---------开始写入标签------>")
                isReadTAG = false
                HHTipUtils.getInstance().showToast(this@NFCTAGActivity, "开始写入标签")
            }
        }
    }

    override fun onStart() {
        super.onStart()
        Log.d(TAG, "onStart")
        //此处adapter需要重新获取，否则无法获取message
        nfcUtils.nfcInit( this,  this.javaClass)
    }

    override fun onResume() {
        super.onResume()
        Log.d(TAG, "onResume")
        //设置处理优于所有其他NFC的处理
        nfcUtils.onResume(this)
    }

    override fun onPause() {
        super.onPause()
        Log.d(TAG, "onPause")
        //恢复默认状态
        nfcUtils.onPause(this)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        LogUtils.i("onNewIntent action : " + intent.action)
        if (isReadTAG) { // 读取标签
            readTag(intent)
        } else { // 写标签
            writeTag(intent)
        }
    }

    private fun readTag(intent: Intent) {
        try {
            if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action || NfcAdapter.ACTION_TECH_DISCOVERED == intent.action) {
                val rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
                if (!rawMessages.isNullOrEmpty()) {
                    val ndefMessage = rawMessages[0] as NdefMessage
                    val records = ndefMessage.records
                    appendLog("\n----------读取标签records.size ： ${records.size}")
                    for (record  in records) {
                        if (record.tnf == NdefRecord.TNF_WELL_KNOWN) {
                            if (Arrays.equals(record.type, NdefRecord.RTD_TEXT)) {
                                //获得字节数组，然后进行分析
                                val payload: ByteArray = record.payload
                                //下面开始NDEF文本数据第一个字节，状态字节
                                //判断文本是基于UTF-8还是UTF-16的，取第一个字节"位与"上16进制的80，16进制的80也就是最高位是1，
                                //其他位都是0，所以进行"位与"运算后就会保留最高位
                                val textEncoding = if (payload[0].toInt() and 0x80 == 0) Charsets.UTF_8 else Charsets.UTF_16
                                //3f最高两位是0，第六位是1，所以进行"位与"运算后获得第六位
                                val languageCodeLength = payload[0].toInt() and 0x3f
                                //下面开始NDEF文本数据第二个字节，语言编码
                                //获得语言编码
                                val languageCode = String(payload, 1, languageCodeLength, Charsets.US_ASCII)
                                //下面开始NDEF文本数据后面的字节，解析出文本
                                val textRecord = String(
                                    payload, languageCodeLength + 1,
                                    payload.size - languageCodeLength - 1, textEncoding
                                )
                                appendLog("\n----------读取标签内容：\n $textRecord")
                            } else if (Arrays.equals(record.type, NdefRecord.RTD_URI)){
                                val payload: ByteArray = record.payload
                                val url = UriPrefixMap.URI_PREFIX_MAP[payload[0]] + String(payload, 1, payload.size - 1)
                                appendLog("\n----------读取标签内容：\n $url")
                                handleUrl(url)
                            }
                        }
                    }
                } else {
                    HHTipUtils.getInstance().showToast(this, "EXTRA_NDEF_MESSAGES is null")
                }
            } else {
                HHTipUtils.getInstance().showToast(this@NFCTAGActivity, "未识别到NFC标签卡")
            }
        }catch (e: Exception){
            HHTipUtils.getInstance().showToast(this@NFCTAGActivity, "读取标签失败")
        }
    }

    private fun handleUrl(text: String) {
        if (text.startsWith("http://") || text.startsWith("https://") || text.startsWith("tel:")) {
            val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(text))
            startActivity(browserIntent)
        } else {
            HHTipUtils.getInstance().showToast(this, "Invalid URL format")
        }
    }

    private fun writeTag(intent: Intent) {
        try {
            val data = layoutNfcTagBinding.etContent.text.toString().trim()
            if (TextUtils.isEmpty(data)) {
                HHTipUtils.getInstance().showToast(this@NFCTAGActivity, "请输入标签内容")
                return
            }
            // 获取标签数据
            val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
            if (tag == null) {
                HHTipUtils.getInstance().showToast(this@NFCTAGActivity, "请将标签放置在手机上")
                return
            }
            // 根据网址创建待写入的数据
            val ndefRecord = if (data.startsWith("http://") || data.startsWith("https://") || data.startsWith("tel:")) {
                NdefRecord.createUri(data)
            } else {
                NdefRecord.createTextRecord(null, data)
            }
            val ndefMessage = NdefMessage(arrayOf(ndefRecord))
            // 获取内容字节大小
            val size = ndefMessage.toByteArray().size
            // 获取Nedf
            val ndef = Ndef.get(tag)
            // 不为空表示该标签为Nedf格式
            if (ndef != null) {
                ndef.connect()
                // 是否可写
                if (!ndef.isWritable) {
                    HHTipUtils.getInstance().showToast(this, "标签不支持写入")
                    return
                }
                // 判断写入内容大小是否超出允许写入的最大值
                if (ndef.maxSize < size) {
                    HHTipUtils.getInstance().showToast(this, "写入内容过大")
                    return
                }
                // 写入数据
                ndef.writeNdefMessage(ndefMessage)
                HHTipUtils.getInstance().showToast(this, "写入成功")
            } else { // 标签非Nedf格式的情况
                val format = NdefFormatable.get(tag)
                // 不为空表示该标签允许格式化成Ndef格式
                if (format != null) {
                    format.connect()
                    // 格式化并写入Nedf内容
                    format.format(ndefMessage)
                    HHTipUtils.getInstance().showToast(this, "写入成功")
                } else {
                    HHTipUtils.getInstance().showToast(this, "标签不支持Nedf格式")
                }
            }
        }catch (e: Exception){
            HHTipUtils.getInstance().showToast(this@NFCTAGActivity, "写入标签异常")
        }
    }

    fun appendLog(log: String) {
        layoutNfcTagBinding.apply {
            if (tvLog.text.trim().isEmpty()) {
                tvLog.text = log
            } else {
                tvLog.append(log)
            }
            mainHandler.postDelayed({ logScroll.fullScroll(View.FOCUS_DOWN) }, 200)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        HHTipUtils.getInstance().dismissProgressDialog()
        mainHandler.removeCallbacksAndMessages(null)
        readCardManager.readCardStop()
    }
}